<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>组合模式实现多层次的对象树管理</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8f9fa;
            color: #333;
            line-height: 1.6;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .code-block {
            background-color: #282c34;
            border-radius: 8px;
            box-shadow: 0 10px 20px rgba(0,0,0,0.1);
        }
        .card {
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 15px 30px rgba(0,0,0,0.15);
        }
        .highlight {
            position: relative;
        }
        .highlight:before {
            content: "";
            position: absolute;
            left: -4px;
            top: 0;
            height: 100%;
            width: 4px;
            background: linear-gradient(to bottom, #667eea, #764ba2);
            border-radius: 4px;
        }
    </style>
</head>
<body class="antialiased">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4">
        <div class="container mx-auto max-w-6xl">
            <div class="flex flex-col items-center text-center">
                <h1 class="text-4xl md:text-5xl font-bold mb-4">组合模式实现多层次的对象树管理</h1>
                <p class="text-xl md:text-2xl max-w-3xl mb-8 opacity-90">
                    优雅处理"部分-整体"层次结构的设计模式
                </p>
                <div class="flex space-x-4">
                    <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                        <i class="fas fa-project-diagram mr-2"></i> 结构型设计模式
                    </span>
                    <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                        <i class="fas fa-code-branch mr-2"></i> 递归结构
                    </span>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-6xl py-12 px-4">
        <!-- Definition Section -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-md overflow-hidden card">
                <div class="p-8">
                    <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                        <i class="fas fa-info-circle text-blue-500 mr-3"></i>
                        组合模式的定义
                    </h2>
                    <p class="text-lg text-gray-700 mb-6">
                        组合模式（Composite Pattern）是结构型设计模式之一，专门用于表示"部分-整体"的层次结构。它允许我们将单个对象和组合对象统一对待，通过递归结构管理和操作多层次对象树。
                    </p>
                    
                    <div class="grid md:grid-cols-3 gap-6 mt-8">
                        <div class="bg-blue-50 p-6 rounded-lg">
                            <div class="text-blue-600 text-2xl mb-3">
                                <i class="fas fa-puzzle-piece"></i>
                            </div>
                            <h3 class="font-bold text-lg mb-2 text-gray-800">组件（Component）</h3>
                            <p class="text-gray-600">定义了对象的通用接口，客户端通过该接口操作对象。</p>
                        </div>
                        <div class="bg-purple-50 p-6 rounded-lg">
                            <div class="text-purple-600 text-2xl mb-3">
                                <i class="fas fa-leaf"></i>
                            </div>
                            <h3 class="font-bold text-lg mb-2 text-gray-800">叶子（Leaf）</h3>
                            <p class="text-gray-600">表示树的叶子节点，不包含子节点。</p>
                        </div>
                        <div class="bg-indigo-50 p-6 rounded-lg">
                            <div class="text-indigo-600 text-2xl mb-3">
                                <i class="fas fa-sitemap"></i>
                            </div>
                            <h3 class="font-bold text-lg mb-2 text-gray-800">容器（Composite）</h3>
                            <p class="text-gray-600">表示树的非叶子节点，包含子节点并实现对子节点的操作。</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Core Concept Section -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-md overflow-hidden card">
                <div class="p-8">
                    <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                        <i class="fas fa-lightbulb text-yellow-500 mr-3"></i>
                        组合模式的核心思想
                    </h2>
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <p class="text-lg text-gray-700 mb-6">
                                组合模式的核心是递归地组织对象，使得客户端能够以一致的方式处理复杂的层次结构。这种递归的思想是通过组合对象树实现的。
                            </p>
                            <ul class="space-y-4">
                                <li class="flex items-start">
                                    <span class="text-blue-500 mr-2 mt-1">
                                        <i class="fas fa-arrow-right"></i>
                                    </span>
                                    <span class="text-gray-700">
                                        <strong>递归结构：</strong>树形结构中，每个容器对象可以包含叶子或其他容器对象，从而形成递归关系。
                                    </span>
                                </li>
                                <li class="flex items-start">
                                    <span class="text-blue-500 mr-2 mt-1">
                                        <i class="fas fa-arrow-right"></i>
                                    </span>
                                    <span class="text-gray-700">
                                        <strong>统一操作：</strong>无论是单个叶子对象还是包含子节点的容器对象，都实现相同的接口，从而实现一致性。
                                    </span>
                                </li>
                            </ul>
                        </div>
                        <div class="flex items-center justify-center">
                            <div class="mermaid">
                                classDiagram
                                    class Component {
                                        <<interface>>
                                        +operation()
                                    }
                                    class Leaf {
                                        +operation()
                                    }
                                    class Composite {
                                        -children: List<Component>
                                        +operation()
                                        +add(Component)
                                        +remove(Component)
                                        +getChildren(): List<Component>
                                    }
                                    Component <|-- Leaf
                                    Component <|-- Composite
                                    Composite *-- Component
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Implementation Section -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-md overflow-hidden card">
                <div class="p-8">
                    <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                        <i class="fas fa-code text-green-500 mr-3"></i>
                        组合模式的实现步骤
                    </h2>
                    
                    <!-- Step 1 -->
                    <div class="mb-10 highlight">
                        <h3 class="text-2xl font-bold mb-4 text-gray-800">1. 定义组件接口</h3>
                        <div class="code-block p-4 mb-6">
                            <pre class="text-gray-200"><code>// 抽象组件，定义通用接口
public interface Component {
    void operation(); // 执行操作
}</code></pre>
                        </div>
                        <p class="text-gray-700">
                            这是组合模式的基础，定义了所有组件（包括叶子节点和容器节点）都必须实现的公共接口。
                        </p>
                    </div>
                    
                    <!-- Step 2 -->
                    <div class="mb-10 highlight">
                        <h3 class="text-2xl font-bold mb-4 text-gray-800">2. 实现叶子节点</h3>
                        <div class="code-block p-4 mb-6">
                            <pre class="text-gray-200"><code>// 叶子节点，没有子节点
public class Leaf implements Component {
    private String name;

    public Leaf(String name) {
        this.name = name;
    }

    @Override
    public void operation() {
        System.out.println("叶子节点 [" + name + "] 执行了操作。");
    }
}</code></pre>
                        </div>
                        <p class="text-gray-700">
                            叶子节点实现了Component接口，代表树结构中的叶子对象，没有子节点。
                        </p>
                    </div>
                    
                    <!-- Step 3 -->
                    <div class="mb-10 highlight">
                        <h3 class="text-2xl font-bold mb-4 text-gray-800">3. 实现容器节点</h3>
                        <div class="code-block p-4 mb-6">
                            <pre class="text-gray-200"><code>import java.util.ArrayList;
import java.util.List;

// 容器节点，包含子节点
public class Composite implements Component {
    private List&lt;Component&gt; children = new ArrayList&lt;&gt;();
    private String name;

    public Composite(String name) {
        this.name = name;
    }

    @Override
    public void operation() {
        System.out.println("容器节点 [" + name + "] 执行了操作。");
        for (Component child : children) {
            child.operation();
        }
    }

    // 添加子节点
    public void add(Component component) {
        children.add(component);
    }

    // 删除子节点
    public void remove(Component component) {
        children.remove(component);
    }

    // 获取子节点
    public List&lt;Component&gt; getChildren() {
        return children;
    }
}</code></pre>
                        </div>
                        <p class="text-gray-700">
                            容器节点也实现了Component接口，但内部可以包含其他组件（叶子或其他容器），形成递归结构。
                        </p>
                    </div>
                    
                    <!-- Step 4 -->
                    <div class="highlight">
                        <h3 class="text-2xl font-bold mb-4 text-gray-800">4. 客户端代码</h3>
                        <div class="code-block p-4 mb-6">
                            <pre class="text-gray-200"><code>public class CompositePatternDemo {
    public static void main(String[] args) {
        // 创建叶子节点
        Leaf leaf1 = new Leaf("叶子节点 1");
        Leaf leaf2 = new Leaf("叶子节点 2");
        Leaf leaf3 = new Leaf("叶子节点 3");

        // 创建容器节点
        Composite composite1 = new Composite("容器节点 1");
        Composite composite2 = new Composite("容器节点 2");

        // 构建树形结构
        composite1.add(leaf1);
        composite1.add(leaf2);

        composite2.add(leaf3);
        composite2.add(composite1);

        // 执行操作
        System.out.println("对组合树执行操作：");
        composite2.operation();
    }
}</code></pre>
                        </div>
                        <div class="bg-blue-50 p-6 rounded-lg">
                            <h4 class="font-bold text-lg mb-3 text-gray-800 flex items-center">
                                <i class="fas fa-terminal text-blue-600 mr-2"></i>
                                输出结果
                            </h4>
                            <div class="bg-gray-800 text-gray-100 p-4 rounded">
                                <pre>对组合树执行操作：
容器节点 [容器节点 2] 执行了操作。
叶子节点 [叶子节点 3] 执行了操作。
容器节点 [容器节点 1] 执行了操作。
叶子节点 [叶子节点 1] 执行了操作。
叶子节点 [叶子节点 2] 执行了操作。</pre>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Pros & Cons Section -->
        <section class="mb-16">
            <div class="grid md:grid-cols-2 gap-8">
                <!-- Advantages -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden card">
                    <div class="p-8">
                        <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                            <i class="fas fa-check-circle text-green-500 mr-3"></i>
                            组合模式的优点
                        </h2>
                        <ul class="space-y-4">
                            <li class="flex items-start">
                                <span class="text-green-500 mr-2 mt-1">
                                    <i class="fas fa-check"></i>
                                </span>
                                <span class="text-gray-700">
                                    <strong>统一性：</strong>通过定义统一接口，客户端可以一致地处理单个对象和组合对象，无需关心它们的具体类型。
                                </span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-green-500 mr-2 mt-1">
                                    <i class="fas fa-check"></i>
                                </span>
                                <span class="text-gray-700">
                                    <strong>递归结构：</strong>支持递归的树形结构，方便实现复杂的层次管理。
                                </span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-green-500 mr-2 mt-1">
                                    <i class="fas fa-check"></i>
                                </span>
                                <span class="text-gray-700">
                                    <strong>灵活性：</strong>通过组合和递归，动态地构建和操作对象树。
                                </span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-green-500 mr-2 mt-1">
                                    <i class="fas fa-check"></i>
                                </span>
                                <span class="text-gray-700">
                                    <strong>开闭原则：</strong>新增节点类型时，只需实现Component接口，不需要修改已有代码。
                                </span>
                            </li>
                        </ul>
                    </div>
                </div>
                
                <!-- Limitations -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden card">
                    <div class="p-8">
                        <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                            <i class="fas fa-exclamation-triangle text-orange-500 mr-3"></i>
                            组合模式的局限性
                        </h2>
                        <ul class="space-y-4">
                            <li class="flex items-start">
                                <span class="text-orange-500 mr-2 mt-1">
                                    <i class="fas fa-exclamation"></i>
                                </span>
                                <span class="text-gray-700">
                                    <strong>类型安全问题：</strong>客户端对叶子节点和容器节点的具体类型不敏感，可能需要额外的类型判断。
                                </span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-orange-500 mr-2 mt-1">
                                    <i class="fas fa-exclamation"></i>
                                </span>
                                <span class="text-gray-700">
                                    <strong>复杂性：</strong>树形结构中层次过深时，可能导致维护困难。
                                </span>
                            </li>
                            <li class="flex items-start">
                                <span class="text-orange-500 mr-2 mt-1">
                                    <i class="fas fa-exclamation"></i>
                                </span>
                                <span class="text-gray-700">
                                    <strong>性能问题：</strong>在大型对象树中，递归操作可能导致性能瓶颈。
                                </span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Use Cases Section -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-md overflow-hidden card">
                <div class="p-8">
                    <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                        <i class="fas fa-sitemap text-purple-500 mr-3"></i>
                        使用场景
                    </h2>
                    <div class="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
                        <div class="bg-gradient-to-br from-blue-50 to-purple-50 p-6 rounded-lg">
                            <div class="text-blue-600 text-3xl mb-4">
                                <i class="fas fa-folder-tree"></i>
                            </div>
                            <h3 class="font-bold text-lg mb-2 text-gray-800">文件系统管理</h3>
                            <p class="text-gray-600">目录（容器节点）和文件（叶子节点）形成的树形结构。</p>
                        </div>
                        <div class="bg-gradient-to-br from-purple-50 to-indigo-50 p-6 rounded-lg">
                            <div class="text-purple-600 text-3xl mb-4">
                                <i class="fas fa-paint-brush"></i>
                            </div>
                            <h3 class="font-bold text-lg mb-2 text-gray-800">图形绘制系统</h3>
                            <p class="text-gray-600">图形组合（容器节点）和基本图形（叶子节点）。</p>
                        </div>
                        <div class="bg-gradient-to-br from-indigo-50 to-blue-50 p-6 rounded-lg">
                            <div class="text-indigo-600 text-3xl mb-4">
                                <i class="fas fa-users"></i>
                            </div>
                            <h3 class="font-bold text-lg mb-2 text-gray-800">组织结构管理</h3>
                            <p class="text-gray-600">部门（容器节点）和员工（叶子节点）的层次关系。</p>
                        </div>
                        <div class="bg-gradient-to-br from-blue-50 to-purple-50 p-6 rounded-lg">
                            <div class="text-blue-600 text-3xl mb-4">
                                <i class="fas fa-window-maximize"></i>
                            </div>
                            <h3 class="font-bold text-lg mb-2 text-gray-800">UI组件开发</h3>
                            <p class="text-gray-600">窗口（容器节点）和控件（叶子节点）的嵌套关系。</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Visualization Section -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-md overflow-hidden card">
                <div class="p-8">
                    <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                        <i class="fas fa-diagram-project text-red-500 mr-3"></i>
                        组合模式结构图
                    </h2>
                    <div class="mermaid text-center">
                        classDiagram
                            direction TB
                            
                            class Client {
                                +useComponent()
                            }
                            
                            class Component {
                                <<interface>>
                                +operation()
                                +add(Component)
                                +remove(Component)
                                +getChild(int)
                            }
                            
                            class Leaf {
                                +operation()
                            }
                            
                            class Composite {
                                -children: List~Component~
                                +operation()
                                +add(Component)
                                +remove(Component)
                                +getChild(int)
                            }
                            
                            Client --> Component
                            Component <|-- Leaf
                            Component <|-- Composite
                            Composite o-- Component
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12">
        <div class="container mx-auto max-w-6xl px-4">
            <div class="flex flex-col items-center">
                <div class="text-2xl font-bold mb-4 text-white">技术小馆</div>
                <a href="http://www.yuque.com/jtostring" class="hover:text-white transition-colors duration-200">
                    <i class="fas fa-link mr-2"></i> http://www.yuque.com/jtostring
                </a>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            fontFamily: 'Noto Sans SC',
            themeVariables: {
                primaryColor: '#764ba2',
                primaryBorderColor: '#764ba2',
                lineColor: '#667eea',
                textColor: '#333',
                nodeBorder: '#764ba2'
            }
        });
    </script>
</body>
</html>